package controleur;

import java.io.IOException;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import modele.Config;
import modele.FacadeArticle;
import modele.FacadeMembre;
import modele.FacadeMenu;
import modele.FacadeSite;
import modele.InfoSession;
import modele.Membre;
import modele.ValidationForm;

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

/**
 * Récupère et traite les actions provenant de formulaire
 *
 */
// Pourait être scindé en plusieurs formulaire
 public class FormAction extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
   static final long serialVersionUID = 1L;
   
   @EJB FacadeMembre fm;
   @EJB FacadeMenu fmenu;
   @EJB FacadeSite facadeSite;
   @EJB FacadeArticle fa;
    /* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public FormAction() {
		super();
	}   	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// configure l'encodage du texte issue des formulaires 
		// afin de permettre l'enregistrement de caractères spéciaux 
		// dans la base
		request.setCharacterEncoding("UTF-8");
		
		// Session utilisateur
		HttpSession session = request.getSession(true);
		InfoSession infoSession = (InfoSession)session.getAttribute("infoSession");
		
		// utilisateur connecte?
		boolean connecte = infoSession != null && infoSession.getConnecte();
		
		// action associé au formulaire
		String action=request.getParameter("action");
		
		String pageInclue = "accueil.jsp";
		String erreur = null;
		
		if(action == null || action.equals("") && connecte){
			pageInclue = "accueil.jsp";
		}
		else if(action.equals("connexion")){
			
			String id = request.getParameter("id");
			String mdp = request.getParameter("mdp");
			
			if(id != null && mdp != null){
				
				// Verifie les identifiants de connexion
				Membre m = fm.connexion(id, mdp);
				
				if(m!=null){ // les identifiants correct et le compte utilisateur  est activé
					
					pageInclue = "accueil.jsp";
					
					if(infoSession == null){ 
						// Créer une nouvelle session
						// a laquelle on associe les informations sur le membre qui vient de se connecter
						infoSession = new InfoSession();
						infoSession.setConnecte(true);
						infoSession.setMembre(m);
						session.setAttribute("infoSession", infoSession);
					}
					else{ 
						// met a jour la session utilisateur
						infoSession.setConnecte(true);
					}
				}
				else{
					erreur = "L'adresse e-mail ou le mot de passe est invalide";
					pageInclue = "connexion.jsp";
				}
			}
		}
		else if(action.equals("inscription") && !connecte){
			
			String err = "";
			String nom = request.getParameter("nom");
			String prenom = request.getParameter("prenom");
			
			String pseudo = request.getParameter("pseudo");
			String email = request.getParameter("email");
			String mdp = request.getParameter("mdp");
			String mdp2 = request.getParameter("mdp2");

			// Validation du formulaire d'inscription
			
			// messages à afficher en cas d'erreur pour chaque type d'erreur
			ValidationForm.ErreurRequis = "<p>Le champs <strong>%s</strong> est requis pour l'inscription</p>";
			ValidationForm.ErreurIdentique = "<p>Les champs <strong>%s</strong> et <strong>%s</strong> doivent être identique</p>";
			ValidationForm.ErreurEmailInvalide = "<p>Le champs <strong>%s</strong> doit contenir une adresse email valide</p>";
			
			// Verifie que les champs requis sont bien renseignés
			err += ValidationForm.champsRequis("Pseudo", pseudo);
			err += ValidationForm.champsRequis("Adresse e-mail", email);
			err += ValidationForm.champsRequis("Mot de passe", mdp);
			err += ValidationForm.champsRequis("Confirmation du mot de passe", mdp2);
			
			// verifie que les champs 'mot de passe' et 'confirmation du mot de passe' sont bien identiques
			err += ValidationForm.champsIdentique("Mot de passe", "Confirmation du mot de passe", mdp, mdp2);
			
			// verifie que l'email est correcte 
			err += ValidationForm.champsEmailValide("Adresse email", email);
			
			
			if(err.equals("")){ // Le formulaire est valide
				
				// création du nouveau membre
				Membre m = new Membre();
				m.setNom(nom);
				m.setPrenom(prenom);
				m.setPseudo(pseudo);
				m.setPassword(mdp);
				m.setMail(email);
				
				// enregistrement du nouveau membre dans la base
				if(fm.inscription(m)){
					pageInclue = "inscriptionSuccues.jsp";
				}
				else{
					request.setAttribute("texteErr", "l'inscription");
					pageInclue = "erreur.jsp";
				}
				
			}
			else{
				erreur = err;
				pageInclue = "inscription.jsp";
			}
			
			
		}
		else if (action.equals("modificationCompte") && connecte) {
			
			String err = "";
			String nom = request.getParameter("nom");
			String prenom = request.getParameter("prenom");
			
			String pseudo = request.getParameter("pseudo");
			String email = request.getParameter("email");
			String mdp = request.getParameter("mdp");
			String mdp2 = request.getParameter("mdp2");
			
			// Validation du formulaire de modification des données personnelles
			
			// messages à afficher en cas d'erreur pour chaque type d'erreur
			ValidationForm.ErreurRequis = "<p>Le champs <strong>%s</strong> est requis pour l'inscription</p>";
			ValidationForm.ErreurIdentique = "<p>Les champs <strong>%s</strong> et <strong>%s</strong> doivent être identique</p>";
			ValidationForm.ErreurEmailInvalide = "<p>Le champs <strong>%s</strong> doit contenir une adresse email valide</p>";
			
			// Verifie que les champs requis sont bien renseignés
			err += ValidationForm.champsRequis("Pseudo", pseudo);
			err += ValidationForm.champsRequis("Adresse e-mail", email);
			err += ValidationForm.champsRequis("Mot de passe", mdp);
			err += ValidationForm.champsRequis("Confirmation du mot de passe", mdp2);
			
			// verifie que les champs 'mot de passe' et 'confirmation du mot de passe' sont bien identiques
			err += ValidationForm.champsIdentique("Mot de passe", "Confirmation du mot de passe", mdp, mdp2);
			
			// verifie que l'email est correcte 
			err += ValidationForm.champsEmailValide("Adresse email", email);
			
			if(err.equals("")){ // Le formulaire est valide
				
				// modifie les information du membre
				Membre m = infoSession.getMembre();
				m.setNom(nom);
				m.setPrenom(prenom);
				m.setPseudo(pseudo);
				m.setPassword(mdp);
				m.setMail(email);
				
				// enregistre les modification dans la base
				fm.modificationCompte(m);
			}
			else{
				erreur = err;
				pageInclue = "modificationCompte.jsp";
			}
		}
		else if(action.equals("supprimer") && connecte){
			
			String idArticle = request.getParameter("idArticle");
			
			if(idArticle != null && !idArticle.equals("")){
				
				try{
					
					long id = Long.parseLong(idArticle);
					
					// verifie que le membre est bien l'auteur de l'article auquel cas 
					// celui-ci est suprimer
					if(fa.supprimerArticle(infoSession.getMembre(), id)){
						// met à jours les informations de session
						infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
						pageInclue = "succesSuppressionArticle.jsp";
					}
					else{
						request.setAttribute("texteErr", "la suppression de votre article");
						pageInclue = "erreur.jsp";
					}
					
				}catch(NumberFormatException e){
					
					e.printStackTrace();
					pageInclue = "accueil.jsp";
				}
			}
		}
		else if(action.equals("publication") && connecte){
			
			String titre = request.getParameter("titreArticle");
			String sport = request.getParameter("sportArticle");
			String competition = request.getParameter("competitionsArticle");
			String article = request.getParameter("article");
			String err = "";
			
			// messages à afficher en cas d'erreur pour chaque type d'erreur
			ValidationForm.ErreurRequis = "<p>Le champs <strong>%s</strong> est requis pour publier l'article</p>";
			ValidationForm.ErreurArticleRequis = "<p>Le champs <strong>%s</strong> est requis pour publier l'article</p>";
			ValidationForm.ErreurSelectionRequis = "<p>Vous devez sélectionner le champ <strong>%s</strong></p>";
			
			// Verifie que les champs requis sont bien renseignés
			err += ValidationForm.champsRequis("Titre de l'article", titre);
			err += ValidationForm.champsArticleRequis("Article", article);
			err += ValidationForm.champsArticleRequis("sport", sport);
			err += ValidationForm.champsArticleRequis("compétition", competition);
			
			if(err.equals("") && sport != null){ // Le formulaire est valide
				
				long idSport = Long.parseLong(sport);
				Long idCompetition = Long.parseLong(competition);
				
				
				if(idCompetition < 1) idCompetition = null; // l'article n'est associé a aucune competition en particulier
				
				// Sécurise le titre de l'article en le netoyant de toutes balise HTML
				titre = Jsoup.clean(titre, Whitelist.none());
				
				// Nétoie le texte de l'article en autorisant seulement le balises a, b, blockquote, br, cite, code, dd, dl, dt, em, 
				// i, li, ol, p, pre, q, small, strike, strong, sub, sup, u, ul ainsi que les attributs necessaire en autorisant 
				// en plus les balise table, tr, td ainsi que la balise img avec les attributs associés style, width et height
				Whitelist w = Whitelist.basicWithImages()
								.addAttributes("table", "tr", "td")
								.addAttributes("img", "style", "width", "height");
				// assainie le code HTML de l'article et le sécurise en prevenant les faille XSS
				article = Jsoup.clean(article, w);

				// enregistre l'article dans la base de donnée
				if(fa.redigerArticle(infoSession.getMembre(), idSport, idCompetition, article, titre)){
					pageInclue = "succesPublication.jsp";
					
					//TODO verifier si on doit rafraichir le membre centenu dans la session
					infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
				}
				else{
					request.setAttribute("texteErr", "la publication de votre article");
					pageInclue = "erreur.jsp";
					
				}
			}
			else{
				erreur = err;
				request.setAttribute("sports", facadeSite.getSports());
				pageInclue = "redactionArticle.jsp";
			}
		}
		else if(action.equals("creationCompetition") && connecte){
			
			String titre = request.getParameter("titreCompetition");
			String sport = request.getParameter("sportCompetition");
			
			if(sport != null && titre != null){
			
				String err = "";
				
				// Verifie que les champs requis sont bien renseignés
				ValidationForm.ErreurRequis = "<p>Le champs <strong>%s</strong> est requis pour publier l'article</p>";
				ValidationForm.ErreurSelectionRequis = "<p>Vous devez sélectionner le champ <strong>%s</strong></p>";
				
				// Verifie que les champs requis sont bien renseignés
				err += ValidationForm.champsRequis("Nom de la compétition", titre);
				err += ValidationForm.champsSelectionRequis("sport", sport);
				
				if(err.equals("")){ // Le formulaire est valide
					try{
						
						long idSport = Long.parseLong(sport);
						
						// ajoute la competition dans la base de données
						if(fa.ajouterCompetition(infoSession.getMembre(), idSport, titre)){
							pageInclue = "succesCreationCompetition.jsp";
							
						}
						else{
							request.setAttribute("texteErr", "l'ajout de votre competition");
							pageInclue = "erreur.jsp";
						}
					}
					catch (NumberFormatException e) {
						e.printStackTrace();
						pageInclue = "accueil.jsp";
					}
				}
				else{
					erreur = err;
					request.setAttribute("sports", facadeSite.getSports());
					pageInclue = "creationCompetition.jsp";
				}
			}
			else{
				pageInclue = "accueil.jsp";
			}
		}
		else if(action.equals("approbation") && connecte){
			
			String idart = (String) request.getParameter("idart");
			String idCom = (String) request.getParameter("idcom");
			
			if(idCom != null && idart != null){
				
				try{
				
					long idCommentaire = Long.parseLong(idCom);
					
					// ajoute une approbation sur un commentaire
					if(fa.approuverCommentaire(infoSession.getMembre(), idCommentaire)){
						
						long idArticle  = Long.parseLong(idart);
						
						// retour sur la page de l'article
						request.setAttribute("article", fa.majArticle(idArticle));	
						infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
						pageInclue = "article.jsp";
					}
					else{
						request.setAttribute("texteErr", "l'approbation de ce commentaire");
						pageInclue = "erreur.jsp";
					}
				}
				catch (NumberFormatException e) {
					e.printStackTrace();
					pageInclue = "accueil.jsp";
				}
			}
			else{
				pageInclue = "accueil.jsp";
			}
			
		}
		else if (action.equals("note") && connecte){
			
			String idart = (String) request.getParameter("idart");
			String n =(String) request.getParameter("note");
			
			if(idart != null && n != null){
				
				try{
					
					Long idArticle=Long.parseLong(idart);
					
					
					if(n.equals("--")){
						pageInclue = "article.jsp";
						request.setAttribute("article", fa.majArticle(idArticle));	
						//infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
					}
		
					int note = Integer.valueOf(n);
					
					// ajoute une note a l'article
					if(fa.noterArticle(infoSession.getMembre(), idArticle, note)){
						pageInclue = "article.jsp";
						request.setAttribute("article", fa.majArticle(idArticle));	
						infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
					}
					else{
						request.setAttribute("texteErr", "la notation de cet article");
						pageInclue = "erreur.jsp";
					}
				}
				catch (NumberFormatException e) {
					e.printStackTrace();
					pageInclue = "accueil.jsp";
				}
			}
		}
		else if (action.equals("commenter") && connecte){
			
			String idart = (String) request.getParameter("idart");
			String text =(String) request.getParameter("text");
			
			if(idart != null && text != null){
				
				Long idArticle=Long.parseLong(idart);
				
				if(text.equals("")){
					erreur = "Veuillez rentrez un commentaire";
					request.setAttribute("article", fa.majArticle(Long.parseLong(idart)));
					pageInclue = "article.jsp";
				}
				// ajoute un commentaire a l'article
				else if(fa.commenterArticle(infoSession.getMembre(), Long.parseLong(idart), text)){
					
					// retour à l'article 
					pageInclue = "article.jsp";
					request.setAttribute("article", fa.majArticle(idArticle));	
					infoSession.setMembre(fm.majMembre(infoSession.getMembre().getId()));
				
				}
				else{
					request.setAttribute("texteErr", "l'ajout de votre commentaire");
					pageInclue = "erreur.jsp";
				}
			}
	
		}

		else{
			pageInclue = "accueil.jsp";
		}
		
		
		if(pageInclue.equals("accueil.jsp")){
			
			request.getRequestDispatcher("Site?page=accueil").forward(request, response);
			
		}else{
			request.setAttribute("idsSports", this.facadeSite.getIdsSports());
			request.setAttribute("formatDate", Config.sdf);
			request.setAttribute("infoSession", infoSession);
			request.setAttribute("erreur", erreur);
			request.setAttribute("Menu", fmenu.getMenu());
			request.setAttribute("pageInclue", pageInclue);
			request.getRequestDispatcher("index.jsp").forward(request, response);
		}
	}
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response);
	}   	  	    
}